#if !defined(_AXML_H_)
#define _AXML_H_

#include "AObject.h"
#include "CCSAXParser.h"

class CAXMLNode;

typedef CCArray CAXMLNodes;

class CAXMLNode : public CAObject
{
protected:
	CAStringMap<CAXMLNodes>* _nodes;
	//map<CAString, CAXMLNodes> nodes;
	map<CAString, CAString> _attrs;
	
	CAString _name;
	CAString _text;
public:
	CAXMLNode();
	virtual ~CAXMLNode();

	inline const CAString& name() const { return _name; }
	inline const CAString& text() const { return _text; }
	inline map<CAString, CAString>& attrs() { return _attrs; }
	inline CAString& attr(const char* key) 
	{ 
		return _attrs[key]; 
	}
	inline bool hasAttr(const char* key)
	{
		if (_attrs.find(key) == _attrs.end())
			return false;
		return true;
	}
	inline CAXMLNodes* nodes(const char* key) 
	{ 
		return (CAXMLNodes*)_nodes->objectForKey(key); 
	}
	inline bool hasNode(const char* key)
	{
		return null != _nodes->objectForKey(key);
	}
	inline CAXMLNode* firstnode(const char* key)
	{
		CAXMLNodes* pnodes = nodes(key);
		if (null != pnodes)
		{
			_Assert(pnodes->count() == 1); //if firstnode ==> exist and only one
			CAXMLNode* pnode = (CAXMLNode*)pnodes->objectAtIndex(0);
			_Assert(pnode);
			return pnode;
		}
		return null;
	}

	inline void setName(const char* name) { _name = name; }
	inline void setText(const char* text) { _text = text; }
	inline void addAttr(const char* key, const char* attr) { _attrs[key] = attr; }

	void addNode(const char* group, CAXMLNode* pnode)
	{
		CAXMLNodes* pns = nodes(group);
		if (NULL == pns)
		{
			pns = CAXMLNodes::arrayWithCapacity(2);
			_nodes->setObject(pns, group);
		}
		pns->addObject(pnode);
	}

	//xxx
	//@xxx
	//xxx.xxx:2.xxx@xxx
	//CAString getAttr(const CAString& name);

	//xxx.xxx.xxx.xxx
	//const vector<CAXMLNode*>& getNodes(const CAString& name);
	//CAXMLNode* getNode(const CAString& name);
};

class CAXML : public CAXMLNode, CCSAXDelegator
{
protected:
	//for parsing
	stack<CAXMLNode*> _nodesStack;
	CAXMLNode* _curnode();
public:
	CAXML(void);
	virtual ~CAXML(void);

	// implement pure virtual methods of CCSAXDelegator
	void startElement(void *ctx, const char *name, const char **atts);
	void endElement(void *ctx, const char *name);
	void textHandler(void *ctx, const char *ch, int len);

	static CAXML* parse(const char* pszFile, bool bCache);
};

#endif //_AXML_H_